import 'dart:convert';
import 'package:http/http.dart' as http;

import 'models.dart';

/// 适配豆瓣相关热门接口
class DoubanService {
  static const Map<String, String> _headers = {
    'User-Agent':
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
    'Referer': 'https://movie.douban.com/',
  };

  // 将豆瓣封面链接转换为更高清的版本
  static String? _toLargeCover(String? url) {
    if (url == null) return null;
    var u = url;
    // 常见：/view/photo/s_ratio_poster/public/pXXXX.jpg -> l_ratio_poster
    u = u.replaceAll('/s_ratio_poster/', '/l_ratio_poster/');
    // 兜底：small/medium -> large
    u = u.replaceAll('/small/', '/large/');
    u = u.replaceAll('/medium/', '/large/');
    return u;
  }

  /// 热门剧集（GET）
  static Future<List<VodItem>> fetchHotTv({int pageStart = 0, int pageLimit = 50}) async {
    final uri = Uri.parse(
        'https://movie.douban.com/j/search_subjects?type=tv&tag=热门&page_limit=$pageLimit&page_start=$pageStart');
    final resp = await http.get(uri, headers: _headers);
    if (resp.statusCode != 200) {
      throw Exception('豆瓣热门剧集请求失败: ${resp.statusCode}');
    }
    final data = jsonDecode(resp.body) as Map<String, dynamic>;
    final subjects = (data['subjects'] ?? []) as List<dynamic>;
    return subjects.map((e) {
      final m = e as Map<String, dynamic>;
      final id = int.tryParse('${m['id'] ?? 0}') ?? 0;
      final title = '${m['title'] ?? ''}';
      final cover = _toLargeCover(m['cover']?.toString());
      final rate = m['rate']?.toString();
      return VodItem(
        id: id,
        name: title,
        typeName: '剧集',
        pic: cover,
        remarks: (rate ?? '').isEmpty ? null : '评分 $rate',
      );
    }).toList();
  }

  /// 热门综艺（GET）
  static Future<List<VodItem>> fetchHotVariety({int pageStart = 0, int pageLimit = 50}) async {
    final uri = Uri.parse(
        'https://movie.douban.com/j/search_subjects?type=tv&tag=综艺&page_limit=$pageLimit&page_start=$pageStart');
    final resp = await http.get(uri, headers: _headers);
    if (resp.statusCode != 200) {
      throw Exception('豆瓣热门综艺请求失败: ${resp.statusCode}');
    }
    final data = jsonDecode(resp.body) as Map<String, dynamic>;
    final subjects = (data['subjects'] ?? []) as List<dynamic>;
    return subjects.map((e) {
      final m = e as Map<String, dynamic>;
      final id = int.tryParse('${m['id'] ?? 0}') ?? 0;
      final title = '${m['title'] ?? ''}';
      final cover = _toLargeCover(m['cover']?.toString());
      final rate = m['rate']?.toString();
      return VodItem(
        id: id,
        name: title,
        typeName: '综艺',
        pic: cover,
        remarks: (rate ?? '').isEmpty ? null : '评分 $rate',
      );
    }).toList();
  }

  /// 热门动漫（GET）
  static Future<List<VodItem>> fetchHotAnime({int pageStart = 0, int pageLimit = 50}) async {
    final uri = Uri.parse(
        'https://movie.douban.com/j/search_subjects?type=tv&tag=动漫&page_limit=$pageLimit&page_start=$pageStart');
    final resp = await http.get(uri, headers: _headers);
    if (resp.statusCode != 200) {
      throw Exception('豆瓣热门动漫请求失败: ${resp.statusCode}');
    }
    final data = jsonDecode(resp.body) as Map<String, dynamic>;
    final subjects = (data['subjects'] ?? []) as List<dynamic>;
    return subjects.map((e) {
      final m = e as Map<String, dynamic>;
      final id = int.tryParse('${m['id'] ?? 0}') ?? 0;
      final title = '${m['title'] ?? ''}';
      final cover = _toLargeCover(m['cover']?.toString());
      final rate = m['rate']?.toString();
      return VodItem(
        id: id,
        name: title,
        typeName: '动漫',
        pic: cover,
        remarks: (rate ?? '').isEmpty ? null : '评分 $rate',
      );
    }).toList();
  }

  /// 热门韩剧（GET）
  static Future<List<VodItem>> fetchHotKorean({int pageStart = 0, int pageLimit = 50}) async {
    final uri = Uri.parse(
        'https://movie.douban.com/j/search_subjects?type=tv&tag=韩剧&page_limit=$pageLimit&page_start=$pageStart');
    final resp = await http.get(uri, headers: _headers);
    if (resp.statusCode != 200) {
      throw Exception('豆瓣热门韩剧请求失败: ${resp.statusCode}');
    }
    final data = jsonDecode(resp.body) as Map<String, dynamic>;
    final subjects = (data['subjects'] ?? []) as List<dynamic>;
    return subjects.map((e) {
      final m = e as Map<String, dynamic>;
      final id = int.tryParse('${m['id'] ?? 0}') ?? 0;
      final title = '${m['title'] ?? ''}';
      final cover = _toLargeCover(m['cover']?.toString());
      final rate = m['rate']?.toString();
      return VodItem(
        id: id,
        name: title,
        typeName: '韩剧',
        pic: cover,
        remarks: (rate ?? '').isEmpty ? null : '评分 $rate',
      );
    }).toList();
  }

  /// Top250电影（GET）
  static Future<List<VodItem>> fetchTop250Movies({int start = 0, int count = 30}) async {
    final uri = Uri.parse(
        'https://api.douban.com/v2/movie/top250?start=$start&count=$count');
    final resp = await http.post(
      uri,
      headers: {
        ..._headers,
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: {'apikey': '0ab215a8b1977939201640fa14c66bab'},
    );
    if (resp.statusCode != 200) {
      throw Exception('豆瓣Top250电影请求失败: ${resp.statusCode}');
    }
    final data = jsonDecode(resp.body) as Map<String, dynamic>;
    final subjects = (data['subjects'] ?? []) as List<dynamic>;
    return subjects.map((e) {
      final m = e as Map<String, dynamic>;
      final id = int.tryParse('${m['id'] ?? 0}') ?? 0;
      final title = '${m['title'] ?? ''}';
      
      // 处理图片字段：电影API返回的是images对象，包含large、medium、small
      String? cover;
      final images = m['images'];
      if (images is Map<String, dynamic>) {
        cover = images['large']?.toString() ?? 
                images['medium']?.toString() ?? 
                images['small']?.toString();
      }
      
      final rating = (m['rating'] is Map) ? ((m['rating'] as Map)['average']?.toString()) : null;
      return VodItem(
        id: id,
        name: title,
        typeName: 'Top250',
        pic: cover,
        remarks: (rating ?? '').isEmpty ? null : '评分 $rating',
      );
    }).toList();
  }

/// 热门电影（GET）
  static Future<List<VodItem>> fetchHotMoviesGet({int pageStart = 0, int pageLimit = 50}) async {
    final uri = Uri.parse(
        'https://movie.douban.com/j/search_subjects?type=movie&tag=热门&page_limit=$pageLimit&page_start=$pageStart');
    final resp = await http.get(uri, headers: _headers);
    if (resp.statusCode != 200) {
      throw Exception('豆瓣热门电影请求失败: ${resp.statusCode}');
    }
    final data = jsonDecode(resp.body) as Map<String, dynamic>;
    final subjects = (data['subjects'] ?? []) as List<dynamic>;
    return subjects.map((e) {
      final m = e as Map<String, dynamic>;
      final id = int.tryParse('${m['id'] ?? 0}') ?? 0;
      final title = '${m['title'] ?? ''}';
      final cover = _toLargeCover(m['cover']?.toString());
      final rate = m['rate']?.toString();
      return VodItem(
        id: id,
        name: title,
        typeName: '电影',
        pic: cover,
        remarks: (rate ?? '').isEmpty ? null : '评分 $rate',
      );
    }).toList();
  }

  /// 热门电影（POST）
  static Future<List<VodItem>> fetchHotMoviesPost({int start = 0, int count = 30, String city = ''}) async {
    final uri = Uri.parse(
        'https://api.douban.com/v2/movie/in_theaters?city=$city&start=$start&count=$count');
    final resp = await http.post(
      uri,
      headers: {
        ..._headers,
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: {'apikey': '0ab215a8b1977939201640fa14c66bab'},
    );
    if (resp.statusCode != 200) {
      throw Exception('豆瓣热门电影请求失败: ${resp.statusCode}');
    }
    final data = jsonDecode(resp.body) as Map<String, dynamic>;
    final subjects = (data['subjects'] ?? []) as List<dynamic>;
    return subjects.map((e) {
      final m = e as Map<String, dynamic>;
      final id = int.tryParse('${m['id'] ?? 0}') ?? 0;
      final title = '${m['title'] ?? ''}';
      
      // 处理图片字段：电影API返回的是images对象，包含large、medium、small
      String? cover;
      final images = m['images'];
      if (images is Map<String, dynamic>) {
        cover = images['large']?.toString() ?? 
                images['medium']?.toString() ?? 
                images['small']?.toString();
      }
      
      final rating = (m['rating'] is Map) ? ((m['rating'] as Map)['average']?.toString()) : null;
      return VodItem(
        id: id,
        name: title,
        typeName: '电影',
        pic: cover,
        remarks: (rating ?? '').isEmpty ? null : '评分 $rating',
      );
    }).toList();
  }

  /// 搜索影片（POST）
  static Future<List<VodItem>> searchMovies({required String query, int start = 0, int count = 10}) async {
    final uri = Uri.parse('https://api.douban.com/v2/movie/search?q=$query&start=$start&count=$count');
    final resp = await http.post(
      uri,
      headers: {
        ..._headers,
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: {'apikey': '0ab215a8b1977939201640fa14c66bab'},
    );
    if (resp.statusCode != 200) {
      throw Exception('豆瓣搜索请求失败: ${resp.statusCode}');
    }
    final data = jsonDecode(resp.body) as Map<String, dynamic>;
    final subjects = (data['subjects'] ?? []) as List<dynamic>;
    return subjects.map((e) {
      final m = e as Map<String, dynamic>;
      final id = int.tryParse('${m['id'] ?? 0}') ?? 0;
      final title = '${m['title'] ?? ''}';
      var subtypes = '${m['subtype'] ?? ''}';
      String getSubtypeDisplayText(String subtypes) {
        return subtypes == 'tv' ? '剧集' : (subtypes == 'movie' ? '电影' : '其他');
      }

      final typeName = getSubtypeDisplayText(subtypes);
      // 处理图片字段：搜索API返回的是images对象，包含large、medium、small
      String? cover;
      final images = m['images'];
      if (images is Map<String, dynamic>) {
        cover = images['large']?.toString() ?? 
                images['medium']?.toString() ?? 
                images['small']?.toString();
      }
      
      final rating = (m['rating'] is Map) ? ((m['rating'] as Map)['average']?.toString()) : null;
      final year = m['year']?.toString();
      return VodItem(
        id: id,
        name: title,
        typeName: typeName,
        pic: cover,
        remarks: [
          if (year != null && year.isNotEmpty) year,
          if (rating != null && rating.isNotEmpty) '评分 $rating',
        ].join(' / '),
      );
    }).toList();
  }

  /// 获取影片详情（POST）
  static Future<VodDetail?> getMovieDetail(int movieId) async {
    final uri = Uri.parse('https://api.douban.com/v2/movie/subject/$movieId');
    final resp = await http.post(
      uri,
      headers: {
        ..._headers,
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: {'apikey': '0ab215a8b1977939201640fa14c66bab'},
    );
    if (resp.statusCode != 200) {
      throw Exception('豆瓣电影详情请求失败: ${resp.statusCode}');
    }
    final data = jsonDecode(resp.body) as Map<String, dynamic>;
    
    // 使用新的fromDoubanJson工厂方法创建VodDetail
    return VodDetail.fromDoubanJson(data);
  }
}